package com.authority.service.impl;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.authority.common.AuthConstants;
import com.authority.common.SysEnum;
import com.authority.dao.AuthRoleDAO;
import com.authority.dao.AuthSysDAO;
import com.authority.dao.AuthUserRoleDAO;
import com.authority.dao.AuthUserDAO;
import com.authority.entry.AuthSysDO;
import com.authority.entry.AuthUserRoleDO;
import com.authority.entry.AuthUserDO;
import com.authority.query.UserQuery;
import com.authority.result.PageResult;
import com.authority.service.AuthUserRoleService;
import com.authority.utils.CommonUtils;
import com.authority.vo.ExternalUser;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 
 * @modify limeng.g
 *
 */
@Service("authUserRoleService")
@Transactional(rollbackFor = Exception.class)
public class AuthUserRoleServiceImpl implements AuthUserRoleService {

	@Resource
	private AuthUserRoleDAO authUserRoleDAO;

	@Resource
	private AuthRoleDAO authRoleDAO;

	@Resource
	private AuthSysDAO authSysDAO;

	@Resource
	private AuthUserDAO userDAO;

	@Override
	public void modifyAuthUserRole(Long userId, Long sysId, List<AuthUserRoleDO> list) {

		authUserRoleDAO.batchDeleteAuthUserRole(userId, sysId);

		if (!CollectionUtils.isEmpty(list)) {
			authUserRoleDAO.batchInsertAuthUserRole(list);
		}
	}

	@Override
	public String getRoleNamesByUserId(Long sysId, Long userId) {

		List<AuthUserRoleDO> list = authUserRoleDAO.queryRoleByUserId(userId, sysId);

		if (!CollectionUtils.isEmpty(list)) {
			StringBuffer roleNames = new StringBuffer();
			for (AuthUserRoleDO urdb : list) {
				roleNames.append(authRoleDAO.queryNameById(urdb.getRoleId()) + ",");
			}
			return roleNames.substring(0, roleNames.length() - 1);
		}

		return null;

	}

	@Override
	public String getRoleIdsByUserId(Long sysId, Long userId) {

		List<AuthUserRoleDO> list = authUserRoleDAO.queryRoleByUserId(userId, sysId);

		if (!CollectionUtils.isEmpty(list)) {
			StringBuffer roleNames = new StringBuffer();
			for (AuthUserRoleDO urdb : list) {
				roleNames.append(urdb.getRoleId() + ",");
			}
			return roleNames.substring(0, roleNames.length() - 1);
		}

		return null;
	}

	@Override
	public String getUserIdsByRoleId(Long sysId, Long roleId) {

		List<Long> list = authUserRoleDAO.queryUserIdListByRoleId(roleId, sysId);
		StringBuffer userIds = new StringBuffer();

		if (!CollectionUtils.isEmpty(list)) {
			for (Long userId : list) {
				userIds.append(userId.toString() + ",");
			}
		} else {
			userIds.append(",");
		}

		return userIds.substring(0, userIds.length() - 1);
	}

	@Override
	public PageResult<ExternalUser> listUser(Long sysId, Long userId, String account, String userName, Long roleId, Integer status, int index) throws Exception {

		// 1、根据系统id和角色id查询所有配置了角色的用户id
		String userIds = getUserIdsByRoleId(sysId, roleId);

		// 2、获取系统的用户管理方式,根据管理方式获取用户列表
		PageResult<ExternalUser> result = getUserList(sysId, userId, account, userName, status, roleId == null ? null : userIds, index);

		// 4、根据 系统 在ADMIN『用户所属角色』表中 获取所有用户的角色
		fillRoleNames(sysId, result);

		return result;
	}

	private PageResult<ExternalUser> getUserList(Long sysId, Long userId, String account, String userName, Integer status, String userIds, int index)
			throws Exception {

		AuthSysDO db = authSysDAO.queryAuthSysById(sysId);

		PageResult<ExternalUser> result = new PageResult<ExternalUser>();
		if (db.getType().equals(SysEnum.ADMIN.getIndex())) {

			result = getAdminExtUser(userId, account, userName, status, userIds, index);
		} else {

			result = getNotAdminExtUser(db.getUserInterface(), userId, account, userName, status, userIds, index);
		}

		return result;
	}

	private PageResult<ExternalUser> getNotAdminExtUser(String inter, Long userId, String account, String userName, Integer status, String userIds, int index)
			throws Exception {

		PageResult<ExternalUser> result = new PageResult<ExternalUser>();
		List<ExternalUser> eList = Lists.newArrayList();
		try {
			WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
			Object obj = context.getBean(inter.substring(0, inter.indexOf(AuthConstants.SEPARATOR_PERIOD)));
			Method method = obj.getClass().getMethod(inter.substring(inter.indexOf(AuthConstants.SEPARATOR_PERIOD) + 1, inter.length()),
					new Class[] { Long.class, String.class, String.class, Integer.class, String.class, int.class });
			PageResult<?> oPage = (PageResult<?>) method.invoke(obj, new Object[] { userId, account, userName, status, userIds, index });
			CommonUtils.doTrans(oPage, result);
			for (Object object : oPage.getList()) {
				ExternalUser eUser = new ExternalUser();
				CommonUtils.doTrans(object, eUser);
				eList.add(eUser);
			}
			result.setList(eList);
		} catch (Exception e) {
			throw new Exception("调用用户查询接口失败！！");
		}

		return result;
	}

	private PageResult<ExternalUser> getAdminExtUser(Long userId, String account, String userName, Integer status, String userIds, int index) throws Exception {

		PageResult<ExternalUser> result = new PageResult<ExternalUser>();
		List<AuthUserDO> list = Lists.newArrayList();
		List<ExternalUser> eList = Lists.newArrayList();
		PageResult<AuthUserDO> page = new PageResult<AuthUserDO>();

		UserQuery query = new UserQuery();
		query.setId(userId);
		if(!StringUtils.isBlank(account)) query.setAccount(account);
		if(!StringUtils.isBlank(userName)) query.setUserName(userName);
		query.setStatus(status);
		if(!StringUtils.isBlank(userIds)) query.setUserIds(userIds);
		query.setIndex(index);
		list = userDAO.queryUserListForAuth(query);

		page = getPageResult(list, userDAO.queryUserListCountForAuth(query), query.getIndex(), query.getNum());
		CommonUtils.doTrans(page, result);
		for (AuthUserDO udb : page.getList()) {
			ExternalUser eUser = new ExternalUser();
			CommonUtils.doTrans(udb, eUser);
			eList.add(eUser);
		}
		result.setList(eList);

		return result;
	}

	private void fillRoleNames(Long sysId, PageResult<ExternalUser> result) {

		for (ExternalUser user : result.getList()) {
			user.setRoleNames(getRoleNamesByUserId(sysId, user.getId()));
		}

	}

	private PageResult<AuthUserDO> getPageResult(List<AuthUserDO> list, int totalNum, Integer index, int num) {

		PageResult<AuthUserDO> result = new PageResult<AuthUserDO>();
		result.setList(list);
		result.setTotalNum(totalNum);
		result.setIndex(index);
		result.setNum(num);

		return result;
	}

	// private void matchUsers(String userIds,List<ExternalUser> list){
	//
	// if(!"".equals(userIds)){
	// String[] userArr = userIds.split(",");
	// Map<String,ExternalUser> map = mapExternalUser(list);
	// for(String str : userArr){
	// ExternalUser user = map.get(str);
	// if(user == null){
	// user = new ExternalUser();
	// user.setId(Long.parseLong(str));
	// user.setStatus(2); // 用户的状态在用户表中有两种（0 禁用，1 正常） 自己在程序中添加3 用户不存在 后续看有什么更好的表示方式
	// list.add(user);
	// }
	// }
	// }
	//
	// }

	// private Map<String,ExternalUser> mapExternalUser(List<ExternalUser> list){
	//
	// Map<String,ExternalUser> map = Maps.newHashMap();
	// for(ExternalUser user : list){
	// map.put(user.getId().toString(), user);
	// }
	//
	// return map;
	// }

}
